package com.hilda.HTMLParserTesting.jtidy;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.tidy.Tidy;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.hilda.HTMLParserTesting.utils.SdCardUtils;

/**
 * Jtidy are very simple, but only parse the website withou any images, CSS o
 * JS. TODO mix Jtidy with another parser
 * 
 * @author olidroide
 */
public class HildaJtidy {
	private Context mContext;
	private URL mURL;
	private Tidy mTidy;
	private SdCardUtils mSdCardUtils;

	public HildaJtidy(Context c) {

		mContext = c;
		mTidy = new Tidy();
		mSdCardUtils = new SdCardUtils(mContext);
	}

	public void parse(String url) {
		Log.v("crawDroid", ".Jtidy: Start parser " + url);

		if (!url.endsWith("/"))
			url += "/";

		try {
			mURL = new URL(url);
		} catch (MalformedURLException e) {
			Log.e("crawDroid", ".Jtidy: " + e.getMessage());
		}

		DowloadWebTask dowloadWebTask = new DowloadWebTask();
		dowloadWebTask.execute();
	}

	private class DowloadWebTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			Log.i("crawDroid", ".Jtidy: Start  AsyncTask");

			File file = mSdCardUtils.prepareFile(mURL, null);

			try {
				PrintWriter out = new PrintWriter(file);
				InputStream in = mURL.openStream();

				// Magic inside here :D
				mTidy.parse(in, out);
				in.close();
				out.close();

				in = mURL.openStream();
				Document document = mTidy.parseDOM(in, null);
				Log.d("crawDroid",
						".Jtidy: documentURI:" + document.getDocumentURI());
				in.close();

				getImages(document);
				getCSS(document);

			} catch (FileNotFoundException e) {
				Log.e("crawDroid", ".Jtidy: " + e.getMessage());
			} catch (MalformedURLException e) {
				Log.e("crawDroid", ".Jtidy: " + e.getMessage());
			} catch (IOException e) {
				Log.e("crawDroid", ".Jtidy: " + e.getMessage());
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			Log.i("crawDroid", ".Jtidy: Finish AsyncTask");
			super.onPostExecute(result);
		}
	}

	private void getCSS(Document document) {
		ArrayList<String> list = new ArrayList<String>();

		NodeList linkTag = document.getElementsByTagName("link");
		String urlPath;

		if (linkTag != null && linkTag.getLength() > 0) {

			for (int i = 0; i < linkTag.getLength(); i++) {
				urlPath = linkTag.item(i).getAttributes().getNamedItem("href")
						.getNodeValue();
				Log.v("crawDroid", ".Jtidy.getCSS: urlPath = " + urlPath);
				if (urlPath.endsWith(".css")) {
					if (urlPath.startsWith("htt")) {
						list.add(urlPath);
					} else {
						if (urlPath.startsWith("/")) {
							list.add(mURL.toExternalForm()
									+ urlPath.substring(1));
						} else {
							list.add(mURL.toExternalForm() + urlPath);
						}
					}
				}

			}
		}

		for (String name : list) {
			Log.v("crawDroid", ".Jtidy.getCSS: CSS href = " + name);
		}

		savePaths(list, mSdCardUtils.CSS_FOLDER);
	}

	private void getImages(Document document) {
		ArrayList<String> list = new ArrayList<String>();

		NodeList img = document.getElementsByTagName("img");
		String urlPath;

		if (img != null && img.getLength() > 0) {

			for (int i = 0; i < img.getLength(); i++) {
				urlPath = img.item(i).getAttributes().getNamedItem("src")
						.getNodeValue();
				Log.v("crawDroid", ".Jtidy.getImages: urlPath = " + urlPath);

				if (urlPath.startsWith("http://")) {
					list.add(urlPath);
				} else {
					list.add(mURL.toExternalForm() + urlPath);
				}

			}
		}

		for (String name : list) {
			Log.v("crawDroid", ".Jtidy.getImages: image src = " + name);
		}

		savePaths(list, mSdCardUtils.IMAGE_FOLDER);
	}

	private void savePaths(ArrayList<String> urlList, String where) {
		File file;
		URL url;
		String pathSdCard;
		byte bytes[] = new byte[1000];

		for (String urlImgPath : urlList) {
			pathSdCard = urlImgPath;

			// if (urlImgPath.startsWith(mURL))
			// pathSdCard = urlImgPath.substring(mURL.length());

			try {
				url = new URL(urlImgPath);
				file = mSdCardUtils.prepareFile(url, where);
				InputStream in = url.openStream();
				OutputStream out = new FileOutputStream(file);

				int numRead = 0;
				numRead = in.read(bytes);
				while (numRead != -1) {
					out.write(bytes, 0, bytes.length);
					numRead = in.read(bytes);
				}
				out.close();
				in.close();

			} catch (FileNotFoundException e) {
				Log.e("crawDroid", ".Jtidy.savePaths: " + e.getMessage());
			} catch (MalformedURLException e) {
				Log.e("crawDroid", ".Jtidy.savePaths: " + e.getMessage());
			} catch (IOException e) {
				Log.e("crawDroid", ".Jtidy.savePaths: " + e.getMessage());
			}

		}
	}

}
